# Concave
# Copyright (C) 2012 Daniel Malmqvist
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import pygame
import helperfunctions
import g
import heapq
import os
import sys
from xml.etree.ElementTree import ElementTree
from pygame.locals import *

from enemy import Enemy
import math
from sets import Set
from item import Item
import constants

class Map():
    def __init__(self):
        self.tileSize = 32
        self.startX = self.startY = -1
        
        self.oldX = -123123
        self.oldY = -123123
        self.oldWall = 0
        self.oldFloor = 0
        
        self.oldCoord = (-1000,-1000)
        
        
        
        
        
        sheet = pygame.image.load(os.path.join("graphic","mountains.png"))
        
        self.wall = helperfunctions.loadImage(sheet, 1, 1)
        self.floor = helperfunctions.loadImage(sheet, 6, 1)
        
        self.wallSE = helperfunctions.loadImage(sheet, 4, 1)
        self.wallSW = helperfunctions.loadImage(sheet, 3, 1)
        self.wallNE = helperfunctions.loadImage(sheet, 4, 0)
        self.wallNW = helperfunctions.loadImage(sheet, 3, 0)
        
        self.wallN = helperfunctions.loadImage(sheet, 1, 2)
        self.wallW = helperfunctions.loadImage(sheet, 2, 1)
        self.wallS = helperfunctions.loadImage(sheet, 1, 0)
        self.wallE = helperfunctions.loadImage(sheet, 0, 1)
        
        self.wallSolid = helperfunctions.loadImage(sheet, 1, 3)
        self.wallNg = helperfunctions.loadImage(sheet, 1, 4)
        self.wallTest = helperfunctions.loadImage(sheet, 0, 8)
        
        self.wall00 = helperfunctions.loadImage(sheet, 0, 0)
        self.wall02 = helperfunctions.loadImage(sheet, 0, 2)
        self.wall20 = helperfunctions.loadImage(sheet, 2, 0)
        self.wall22 = helperfunctions.loadImage(sheet, 2, 2)
        
        self.wall03 = helperfunctions.loadImage(sheet, 0, 3)
        self.wall04 = helperfunctions.loadImage(sheet, 0, 4)
        self.wall23 = helperfunctions.loadImage(sheet, 2, 3)
        self.wall24 = helperfunctions.loadImage(sheet, 2, 4)
        
        self.wall42 = helperfunctions.loadImage(sheet, 4, 2)
        self.wall14 = helperfunctions.loadImage(sheet, 1, 4)
        self.wall32 = helperfunctions.loadImage(sheet, 3, 2)

        stairsheet = pygame.image.load(os.path.join("graphic","cementstair.png"))
        self.stairUp = helperfunctions.loadImage(stairsheet, 4, 2)
        self.stairUpU = helperfunctions.loadImage(stairsheet, 4, 1)
        self.stairDown = helperfunctions.loadImage(stairsheet, 3, 3)
        
        
        
    def printmap(self):
        """
        Prints the map
        """
        for row in self.map:
            for e in row:
                if e == 0:
                    sys.stdout.write(" ")
                elif e == 1:
                    sys.stdout.write(" ")
                elif e == 3:
                    sys.stdout.write("e")
                elif e == 4:
                    sys.stdout.write("s")
                elif e == 5:
                    sys.stdout.write("f")
                else:
                    sys.stdout.write("#")
            sys.stdout.write("\n")
        
    
    def getWallMap(self, x, y):
        return self.oldWall
    
    
    def getFloorMap(self, x, y):
        # This function was a test to see if it was possible to speed up the game.
        if (x < self.oldCoord[0] or x > self.oldCoord[0] + 400 or y < self.oldCoord[1] or y > self.oldCoord[1] + 300):
            rect = Rect(x-400, y-300, 800, 600)
                
            self.oldFloor = pygame.surface.Surface(rect.size, SRCALPHA)
            
            self.oldFloor.blit(self.floorMap, (0, 0), rect)
            self.oldFloor.set_colorkey(-1, RLEACCEL)
            
            self.oldWall = pygame.surface.Surface(rect.size, SRCALPHA)
            self.oldWall.blit(self.wallMap, (0, 0), rect)
            self.oldWall.set_colorkey(-1, RLEACCEL)
            
            self.oldCoord = (x - 400, y - 300)
            
        return self.oldFloor  
    
    def getCoord(self, x, y):
        return (self.oldCoord[0] - x + 400, self.oldCoord[1] - y + 300)
    
    def loadMap(self, currentMap):
        """
        Generates the images for a given map
        """
        self.maxx = len(currentMap[0])
        self.maxy = len(currentMap)
        
        self.map = currentMap
        
        # Add all the enemies and replace them with walkable tiles
        for x in range(0, self.maxx):
            for y in range(0, self.maxy):
                if self.map[y][x] == 3:
                    e = Enemy(x*32+8, y*32+8, g.getCurrentLevel(), self)

                    g.addEnemy(e)
                    self.map[y][x] = 1
        

        sheet = pygame.image.load(os.path.join("graphic","mountains.png"))

        # Here are all the tiles that any given map needs        
        wall = helperfunctions.loadImage(sheet, 1, 1)
        floor = helperfunctions.loadImage(sheet, 6, 1)
        
        wallSE = helperfunctions.loadImage(sheet, 4, 1)
        wallSW = helperfunctions.loadImage(sheet, 3, 1)
        wallNE = helperfunctions.loadImage(sheet, 4, 0)
        wallNW = helperfunctions.loadImage(sheet, 3, 0)
        
        wallN = helperfunctions.loadImage(sheet, 1, 2)
        wallW = helperfunctions.loadImage(sheet, 2, 1)
        wallS = helperfunctions.loadImage(sheet, 1, 0)
        wallE = helperfunctions.loadImage(sheet, 0, 1)
        
        wallSolid = helperfunctions.loadImage(sheet, 1, 3)
        wallNg = helperfunctions.loadImage(sheet, 1, 4)
        wallTest = helperfunctions.loadImage(sheet, 0, 8)
        
        wall00 = helperfunctions.loadImage(sheet, 0, 0)
        wall02 = helperfunctions.loadImage(sheet, 0, 2)
        wall20 = helperfunctions.loadImage(sheet, 2, 0)
        wall22 = helperfunctions.loadImage(sheet, 2, 2)
        
        wall03 = helperfunctions.loadImage(sheet, 0, 3)
        wall04 = helperfunctions.loadImage(sheet, 0, 4)
        wall23 = helperfunctions.loadImage(sheet, 2, 3)
        wall24 = helperfunctions.loadImage(sheet, 2, 4)
        
        wall42 = helperfunctions.loadImage(sheet, 4, 2)
        wall14 = helperfunctions.loadImage(sheet, 1, 4)
        wall32 = helperfunctions.loadImage(sheet, 3, 2)

        stairsheet = pygame.image.load(os.path.join("graphic","cementstair.png"))
        stairUp = helperfunctions.loadImage(stairsheet, 4, 2)
        stairUpU = helperfunctions.loadImage(stairsheet, 4, 1)
        stairDown = helperfunctions.loadImage(stairsheet, 3, 3)
        
        rect = pygame.Rect((0,0, 32*self.maxx, 32*self.maxy))
        self.floorMap = pygame.Surface(rect.size, pygame.SRCALPHA)
        
        
        # Add all floor tiles and stairs
        for x in range(0, self.maxx):
            for y in range(0, self.maxy):
                if self.map[y][x] != 0:
                    self.floorMap.blit(floor, (32*x, 32*y))
                    
                    if self.map[y][x] == 4:
                        self.floorMap.blit(stairUpU, (32*x, 32*(y-1)))
                        self.floorMap.blit(stairUp, (32*x, 32*y))
                        self.map[y][x] = 1
                        
                        self.startX = x
                        self.startY = y+1
                        
                        g.addItem(Item(x*32, y*32, constants.STAIRUP()))
                        
                    elif self.map[y][x] == 5:
                        self.floorMap.blit(stairDown, (32*x, 32*y))
                        self.map[y][x] = 1
                        
                        g.addItem(Item(x*32, y*32, constants.STAIRDOWN()))

        
        self.wallMap = pygame.Surface(rect.size, pygame.SRCALPHA)
        
        # Generate the wall sheet
        for x in range(0, self.maxx):
            for y in reversed(range(0, self.maxy)):
                nw = n = ne = e = se = s = sw = w = ss = -1
                try: 
                    nw = self.map[y-1][x-1]
                except IndexError:
                    pass
                try:
                    n = self.map[y-1][x]
                except IndexError:
                    pass
                try:
                    ne = self.map[y-1][x+1]
                except IndexError:
                    pass
                try:
                    e = self.map[y][x+1]
                except IndexError:
                    pass
                try:
                    se = self.map[y+1][x+1]
                except IndexError:
                    pass
                try:
                    s = self.map[y+1][x]
                except IndexError:
                    pass
                try:
                    sw = self.map[y+1][x-1]
                except IndexError:
                    pass
                try:
                    w = self.map[y][x-1]
                except IndexError:
                    pass
                try:
                    ss = self.map[y+2][x]
                except IndexError:
                    pass
                
                
                if self.map[y][x] == 2:
                    if s == 2 and e == 2 and nw == 2 and se == 1 and ss == 1:
                        self.floorMap.blit(wallSolid, (32*x, 32*(y)))
                        self.wallMap.blit(wall22, (32*x, 32*(y)))
                    
                    
                    if sw == 1 and w == 2 and s == 2 and ss == 1:
                        self.wallMap.blit(wallSolid, (32*x, 32*(y)))
                        self.wallMap.blit(wall02, (32*x, 32*(y)))
                    
                    if s == 1 and w == 2 and e == 2:
                        self.wallMap.blit(wallN, (32*x, 32*(y-1)))
                        self.floorMap.blit(wallSolid, (32*x, 32*(y)))
                        self.floorMap.blit(wallNg, (32*x, 32*(y+1)))
                    elif n == 1 and w == 2 and e == 2:
                        self.wallMap.blit(wallS, (32*x, 32*(y-1)))
                        if s == 0 or s == -1:
                            self.wallMap.blit(wall, (32*x, 32*(y)))
                    elif e == 1 and n == 2 and s == 2:
                        self.wallMap.blit(wallW, (32*x, 32*(y-1)))
                    elif w == 1 and n == 2 and s == 2:
                        self.wallMap.blit(wallE, (32*x, 32*(y-1)))
                    elif se == 1 and e == 2 and s == 2:
                        self.wallMap.blit(wallSE, (32*x, 32*(y-1)))
                        if s == 2:
                            self.floorMap.blit(wall42, (32*x, 32*(y)))
                        self.floorMap.blit(wall14, (32*x, 32*(y+1)))
                    elif sw == 1 and w == 2 and s == 2:
                        self.wallMap.blit(wallSW, (32*x, 32*(y-1)))
                        if s == 2:
                            self.floorMap.blit(wall32, (32*x, 32*(y)))
                        self.floorMap.blit(wall14, (32*x, 32*(y+1)))
                    elif nw == 1 and w == 2 and n == 2:
                        self.wallMap.blit(wallNW, (32*x, 32*(y-1)))
                        if s == 0 or s == -1:
                            self.wallMap.blit(wall, (32*x, 32*(y)))
                    elif ne == 1 and e == 2 and n == 2:
                        self.wallMap.blit(wallNE, (32*x, 32*(y-1)))
                        if s == 0 or s == -1:
                            self.wallMap.blit(wall, (32*x, 32*(y)))
                    elif w == 1 and nw == 1 and n == 1:
                        self.wallMap.blit(wall00, (32*x, 32*(y-1)))
                    elif w == 1 and sw == 1 and s == 1:
                        self.wallMap.blit(wall02, (32*x, 32*(y-1)))
                        self.floorMap.blit(wall03, (32*x, 32*(y)))
                        self.floorMap.blit(wall04, (32*x, 32*(y+1)))
                        
                    elif n == 1 and ne == 1 and e == 1:
                        self.wallMap.blit(wall20, (32*x, 32*(y-1)))
                    elif s == 1 and se == 1 and e == 1:
                        self.wallMap.blit(wall22, (32*x, 32*(y-1)))
                        self.floorMap.blit(wall23, (32*x, 32*(y)))
                        self.floorMap.blit(wall24, (32*x, 32*(y+1)))
                    
                    elif s == -1 or ss == -1:
                        self.wallMap.blit(wallS, (32*x, 32*(y-1)))
                        self.wallMap.blit(wall, (32*x, 32*(y)))
                        self.wallMap.blit(wall, (32*x, 32*(y)))
                    
                    else:
                        self.wallMap.blit(wallTest, (32*x, 32*(y-1)))

        if self.startX == -1:
            # Add stairs, needs to be done when revisiting a floor.
            for i in g.getItems():
                if i.type == constants.STAIRDOWN():
                    self.startX = (i.x/32)
                    self.startY = (i.y/32) + 1 
                    self.map[i.y/32][i.x/32] = 1
                    self.floorMap.blit(stairDown, (i.x, i.y))
                elif i.type == constants.STAIRUP():
                    self.floorMap.blit(stairUpU, (i.x, (i.y - 32)))
                    self.floorMap.blit(stairUp, (i.x, i.y))
                    self.map[i.y/32][i.x/32] = 1
            
            



    """
    def getTileRow(self, y):
        return None
    
    def getTileColumn(self, x):
        return None



    def getCurrertMapSurface(self, xCoord, yCoord):
        rect = pygame.Rect((0,0, 640, 480))
        if xCoord == self.oldX and yCoord == self.oldY:
            return (self.oldFloor, self.oldWall)
        
        
        wallMap = pygame.Surface(rect.size, pygame.SRCALPHA)
        floorMap = pygame.Surface(rect.size, pygame.SRCALPHA)
        
        
        for x in range(xCoord/32, xCoord/32 + 23):
            for y in reversed(range(yCoord/32, yCoord/32 + 20)):
                if self.map[y][x] != 0:
                    floorMap.blit(self.floor, (32*x-xCoord, 32*y-yCoord))
                if self.map[y][x] == 4:
                    self.floorMap.blit(self.stairUpU, (32*x-xCoord, 32*(y-1)-yCoord))
                    self.floorMap.blit(self.stairUp, (32*x-xCoord, 32*y-yCoord))
                    self.map[y][x] = 1
                    
                    self.startX = x
                    self.startY = y+1
                    
                    g.addItem(Item(x*32, y*32, constants.STAIRUP()))
                    
                elif self.map[y][x] == 5:
                    self.floorMap.blit(self.stairDown, (32*x-xCoord, 32*y-yCoord))
                    self.map[y][x] = 1
                    
                    g.addItem(Item(x*32, y*32, constants.STAIRDOWN()))

        for x in range(xCoord/32, xCoord/32 + 23):
            for y in reversed(range(yCoord/32, yCoord/32 + 20)):
                if self.map[y][x] != 0:
                    
                        
                        
                        
                    nw = n = ne = e = se = s = sw = w = ss = -1
                    try: 
                        nw = self.map[y-1][x-1]
                    except IndexError:
                        pass
                    try:
                        n = self.map[y-1][x]
                    except IndexError:
                        pass
                    try:
                        ne = self.map[y-1][x+1]
                    except IndexError:
                        pass
                    try:
                        e = self.map[y][x+1]
                    except IndexError:
                        pass
                    try:
                        se = self.map[y+1][x+1]
                    except IndexError:
                        pass
                    try:
                        s = self.map[y+1][x]
                    except IndexError:
                        pass
                    try:
                        sw = self.map[y+1][x-1]
                    except IndexError:
                        pass
                    try:
                        w = self.map[y][x-1]
                    except IndexError:
                        pass
                    try:
                        ss = self.map[y+2][x]
                    except IndexError:
                        pass
                    
                
                
                
                
                
                if self.map[y][x] == 2:
                    if s == 2 and e == 2 and w == 2 and n == 2:
                        wallMap.blit(self.wallSolid, (32*x-xCoord, 32*(y-1)-yCoord))
                    
                    if s == 2 and e == 2 and nw == 2 and se == 1 and ss == 1:
                        floorMap.blit(self.wallSolid, (32*x-xCoord, 32*(y)-yCoord))
                        wallMap.blit(self.wall22, (32*x-xCoord, 32*(y)-yCoord))
                    
                    
                    if sw == 1 and w == 2 and s == 2 and ss == 1:
                        wallMap.blit(self.wallSolid, (32*x-xCoord, 32*(y)-yCoord))
                        wallMap.blit(self.wall02, (32*x-xCoord, 32*(y)-yCoord))
                    
                    if s == 1 and w == 2 and e == 2:
                        wallMap.blit(self.wallN, (32*x-xCoord, 32*(y-1)-yCoord))
                        floorMap.blit(self.wallSolid, (32*x-xCoord, 32*(y)-yCoord))
                        floorMap.blit(self.wallNg, (32*x-xCoord, 32*(y+1)-yCoord))
                    elif n == 1 and w == 2 and e == 2:
                        wallMap.blit(self.wallS, (32*x-xCoord, 32*(y-1)-yCoord))
                        if s == 0 or s == -1:
                            wallMap.blit(self.wall, (32*x-xCoord, 32*(y)-yCoord))
                    elif e == 1 and n == 2 and s == 2:
                        wallMap.blit(self.wallW, (32*x-xCoord, 32*(y-1)-yCoord))
                    elif w == 1 and n == 2 and s == 2:
                        wallMap.blit(self.wallE, (32*x-xCoord, 32*(y-1)-yCoord))
                    elif se == 1 and e == 2 and s == 2:
                        wallMap.blit(self.wallSE, (32*x-xCoord, 32*(y-1)-yCoord))
                        if s == 2:
                            floorMap.blit(self.wall42, (32*x-xCoord, 32*(y)-yCoord))
                        floorMap.blit(self.wall14, (32*x-xCoord, 32*(y+1)-yCoord))
                    elif sw == 1 and w == 2 and s == 2:
                        wallMap.blit(self.wallSW, (32*x-xCoord, 32*(y-1)-yCoord))
                        if s == 2:
                            floorMap.blit(self.wall32, (32*x-xCoord, 32*(y)-yCoord))
                        floorMap.blit(self.wall14, (32*x-xCoord, 32*(y+1)-yCoord))
                    elif nw == 1 and w == 2 and n == 2:
                        wallMap.blit(self.wallNW, (32*x-xCoord, 32*(y-1)-yCoord))
                        if s == 0 or s == -1:
                            wallMap.blit(self.wall, (32*x-xCoord, 32*(y)-yCoord))
                    elif ne == 1 and e == 2 and n == 2:
                        wallMap.blit(self.wallNE, (32*x-xCoord, 32*(y-1)-yCoord))
                        if s == 0 or s == -1:
                            wallMap.blit(self.wall, (32*x-xCoord, 32*(y)-yCoord))
                    elif w == 1 and nw == 1 and n == 1:
                        wallMap.blit(self.wall00, (32*x-xCoord, 32*(y-1)-yCoord))
                    elif w == 1 and sw == 1 and s == 1:
                        wallMap.blit(self.wall02, (32*x-xCoord, 32*(y-1)-yCoord))
                        floorMap.blit(self.wall03, (32*x-xCoord, 32*(y)-yCoord))
                        floorMap.blit(self.wall04, (32*x-xCoord, 32*(y+1)-yCoord))
                        
                    elif n == 1 and ne == 1 and e == 1:
                        wallMap.blit(self.wall20, (32*x-xCoord, 32*(y-1)-yCoord))
                    elif s == 1 and se == 1 and e == 1:
                        wallMap.blit(self.wall22, (32*x-xCoord, 32*(y-1)-yCoord))
                        floorMap.blit(self.wall23, (32*x-xCoord, 32*(y)-yCoord))
                        floorMap.blit(self.wall24, (32*x-xCoord, 32*(y+1)-yCoord))
                    
                    elif s == -1 or ss == -1:
                        wallMap.blit(self.wallS, (32*x-xCoord, 32*(y-1)-yCoord))
                        wallMap.blit(self.wall, (32*x-xCoord, 32*(y)-yCoord))
                        wallMap.blit(self.wall, (32*x-xCoord, 32*(y)-yCoord))
                    
        
        
        
        (self.oldFloor, self.oldWall) = (floorMap, wallMap)
        self.oldX = xCoord
        self.oldY = yCoord 
        return (floorMap, wallMap)
                    
                    
    """                 

                
    def canMoveTo(self, hitStartX, hitStopX, hitStartY, hitStopY):
        for x in range (hitStartX, hitStopX):
            for y in range (hitStartY, hitStopY):
                if self.map[y/32][x/32] != 1:
                    return False
        
        return True
    def getWallHitBox(self,x,y):
        if self.map[y][x] != 2:
            return pygame.rect.Rect(-1,-1,0,0)
        elif self.map[y][x-1] == 2 and self.map[y][x+1] == 2:
            return pygame.rect.Rect((x*32+8, y*32, 16, 32))
        elif self.map[y][x - 1] == 2:
            return pygame.rect.Rect((x*32+8, y*32, 24, 32))
        elif self.map[y][x + 1] == 2:
            return pygame.rect.Rect((x*32, y*32, 24, 32))

    
    def astar(self, start, goal):
        # A star algorithm for finding a path to the player
        # Based on algorithm from wikipedia http://en.wikipedia.org/wiki/A*_search_algorithm
        if self.map[goal[1]][goal[0]] == 2:
            print "wall at goal"
            return []
        
        closedset = Set()

        opensetset = Set()
        opensetset.add(start)
        
        openset = []
        heapq.heappush(openset, (0, start))
        
        came_from = dict()
        
        g_score = dict()
        f_score = dict()
        
        g_score[(start[0], start[1])] = 0
        
        #g_score[start] = 0
        f_score[start] = g_score[(start[0], start[1])] + self.heuristic_cost_estimate(start, goal)
        
        
        while len(openset) != 0:
            (score, current) = heapq.heappop(openset)
            opensetset.remove(current)
            
            closedset.add(current)
            
            if current == goal:
                return self.reconstructPath(came_from, goal)
            
            for x in range (-1 + current[0], 2+current[0]):
                for y in range (-1 + current[1], 2+current[1]):
                
                    if current[0] == x and current[1] == y:
                        pass
                    elif (x,y) in closedset:
                        pass
                    elif x < 0 or y < 0:
                        pass
                    elif x >= self.maxx or y >= self.maxy:
                        pass
                    elif self.map[y][x] == 2:
                        pass
                    else:
                        tentative_g_score =  self.heuristic_cost_estimate((x,y), goal) # dist_between(current,neighbor)

                        if (x,y) not in opensetset:
                            heapq.heappush(openset, (tentative_g_score, (x,y)))
                            opensetset.add((x,y))
                            
                            came_from[(x,y)] = (current[0],current[1])
                            g_score[(x,y)] = tentative_g_score
                            f_score[(x,y)] = g_score[(x,y)] + self.heuristic_cost_estimate((x,y), goal)
        
        return []
    def heuristic_cost_estimate(self, node, target):
        return int(math.sqrt(math.pow(node[0] - target[0], 2)  +  math.pow(node[1] - target[1], 2) )*100)
        
    def reconstructPath(self, came_from, current_node):
        
        if came_from.has_key(current_node):
            p = self.reconstructPath(came_from, came_from.pop(current_node))
            p.append(current_node)
            return p
        else:
            return [current_node]
        


    # Functions for tiled maps (currently only city map)    
    def setTileSheet(self, tileStart, tileStop, sheet):
        self.tileSheets.append((tileStart, tileStop, sheet))
    
    def loadTileFromSheets(self, tileNum):
        for (tileStart, tileStop, sheet) in self.tileSheets:
            if tileStart <= tileNum and tileStop >= tileNum:
                # Found right sheet extract image now
                sheet = pygame.image.load(sheet.split("../")[1])
                width = sheet.get_width()/32
                x = (tileNum-tileStart)%width
                y = (tileNum-tileStart)/width
                return helperfunctions.loadImage(sheet, x, y)
        
        print "Couldent find image, id: ",tileNum
        return None
            
    def getTile(self, tileNum):
        try:
            return self.tiles[tileNum]
        except KeyError:
            self.tiles[tileNum] = self.loadTileFromSheets(tileNum)
            return self.tiles[tileNum] 
        
        
    def loadMapTiled(self, mapId):
        """
        Loads tiled maps (currently only the city map)
        Tiled: http://www.mapeditor.org/
        """
        self.tiles = dict() 
        self.tileSheets = []
        tree = ElementTree()
        tree.parse(os.path.join("maps","city.tmx"))
        rootElement = tree.getroot()
        
        
        self.map = [ [ 0 for i in range(int(rootElement.attrib['width'])) ] for j in range(int(rootElement.attrib['height'])) ]
        
        sheets = rootElement.findall("tileset")
        
        for sheet in sheets:
            start = int(sheet.attrib['firstgid'])
            apa = sheet._children[0]
            path = apa.attrib['source']
            iW = int(apa.attrib['width'])/32
            iH = int(apa.attrib['height'])/32
            
            stop = start + iW*iH - 1 
            self.setTileSheet(start, stop, path)
            
            if "test.png" in path:
                specialStart = start
            
        
        layers = rootElement.findall("layer")
        maplayers = dict()

        for layer in layers:
            if layer.attrib['name']:
                if layer.attrib['name'] == "hit":
                    hitlayer = layer._children[0]
                elif layer.attrib['name'] == "special":
                    specialLayer = layer._children[0]
                else:
                    maplayers[int(layer.attrib['name'])] = layer
        
        
        # HIT layer
        rows = hitlayer.text.split("\n")
        rows = rows[1:]
        numRows = len(rows) - 1
        numColumns = len(rows[0].split(",")) - 1

        for y in range(0, numRows):
            elements = rows[y].split(",")
            for x in range(0,numColumns):
                if elements[x] != "0":
                    self.map[y][x] = 2
                else:
                    self.map[y][x] = 1
        
        
        
        rows = specialLayer.text.split("\n")
        rows = rows[1:]
        for y in range(0, numRows):
            elements = rows[y].split(",")
            for x in range(0,numColumns):
                if int(elements[x]) == specialStart+1:
                    self.startX = x
                    self.startY = y
                elif int(elements[x]) == specialStart:
                    g.addItem(Item(x*32, y*32, constants.STAIRDOWN()))
        
        
        
        
        # Build floor and wall images
        rect = pygame.Rect((0,0, 32*numColumns, 32*numRows))
        self.floorMap = pygame.Surface(rect.size, pygame.SRCALPHA)
        self.wallMap = pygame.Surface(rect.size, pygame.SRCALPHA)
        for i in range(1,2):
            layer = maplayers[i]._children[0]
            rows = layer.text.split("\n")[1:]
            for y in range(0, numRows):
                elements = rows[y].split(",")
                for x in range(0,numColumns):
                    if elements[x] != "0":
                        self.floorMap.blit(self.getTile(int(elements[x])), (32*x, 32*y))
        
        for i in range(2,4):
            layer = maplayers[i]._children[0]
            rows = layer.text.split("\n")[1:]
            for y in range(0, numRows):
                elements = rows[y].split(",")
                for x in range(0,numColumns):
                    if elements[x] != "0":
                        self.wallMap.blit(self.getTile(int(elements[x])), (32*x, 32*y))
        
        
        
        
        return self.floorMap
        
        
        
"""
pygame.init()

fontBigger = pygame.font.Font(None, 60)
fontBig = pygame.font.Font(None, 24)
fontNormal = pygame.font.Font(None, 20)


screen = pygame.display.set_mode((1600, 800))

bepa = Map()
ble = bepa.loadMapTiled(0)
clock = pygame.time.Clock()
x = 0
y = 0
apa = 0

while (True):
    apa += 1
    screen.fill((255,255,255))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif (event.type == KEYDOWN):
            if ((event.key == K_UP)):
                y -= 256
            elif ((event.key == K_DOWN)):
                y += 256
            elif ((event.key == K_LEFT)):
                x -= 256
            elif ((event.key == K_RIGHT)):
                x += 256
    
    if apa%50 == 0:
        print x,y
    screen.blit(bepa.floorMap, (-x,-y))
    screen.blit(bepa.wallMap, (-x,-y))
    pygame.display.flip()

    clock.tick(60)


"""